package com.oig.sys.workflow.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.oig.common.constants.CommonEnum;
import com.oig.common.exception.BadRequestException;
import com.oig.common.util.JsonUtil;
import com.oig.sys.workflow.dao.ITbCronJobDao;
import com.oig.sys.workflow.dto.CronJobDto;
import com.oig.sys.workflow.entity.TbCronJob;
import com.oig.sys.workflow.service.ITbCronJobService;
import com.oig.sys.workflow.vo.CronJobVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wuxl
 */
@Slf4j
@Service
public class TbCronJobServiceImpl implements ITbCronJobService {

	private final ITbCronJobDao tbCronJobDao;


	@Autowired
	public TbCronJobServiceImpl(ITbCronJobDao tbCronJobDao){
		 this.tbCronJobDao = tbCronJobDao;
	}

	@Transactional
	@Override
	public CronJobVo addCronJob(CronJobDto cronJobDto, String finishOpts){
		if (!CronExpression.isValidExpression(cronJobDto.getScheduleCron())){
			log.debug("cron:{}", cronJobDto.getScheduleCron());
			throw new BadRequestException("cron 表达是错误") ;
		}
		TbCronJob cronJob = new TbCronJob();
		BeanUtils.copyProperties(cronJobDto, cronJob, "id");
		cronJob.setFinishOpts(finishOpts);
		if (StringUtils.isBlank(cronJob.getEnable())){
			cronJob.setEnable(CommonEnum.FlagEnum.FALSE_FLAG.getCode());
		}
		cronJob.setStatus(CommonEnum.CommonStatusEnum.OK.getCode());
		this.tbCronJobDao.save(cronJob);
		return this.buildVo(cronJob);
	}

	private CronJobVo buildVo(TbCronJob cronJob){
		CronJobVo cronJobVo = new CronJobVo();
		BeanUtils.copyProperties(cronJob, cronJobVo);
		if (StringUtils.isNotBlank(cronJob.getFinishOpts())){
			log.debug("finish opts:{}", cronJob.getFinishOpts());
			cronJobVo.setFinishOpts(JsonUtil.toList(cronJob.getFinishOpts(), String.class));
		}
		return cronJobVo;
	}

	@Transactional
	@Override
	public CronJobVo updateCronJob(CronJobDto cronJobDto, String finishOpts){
		TbCronJob cronJob = this.tbCronJobDao.getCronJobById(cronJobDto.getId()) ;
		BeanUtils.copyProperties(cronJobDto, cronJob, "createUserId","createUserName","createTime","tenantId", "tenantName");
		cronJob.setFinishOpts(finishOpts);
		this.tbCronJobDao.save(cronJob);
		return this.buildVo(cronJob);
	}

	@Override
	public CronJobVo getCronJob(Integer id) {
		TbCronJob cronJob = this.tbCronJobDao.getCronJobById(id) ;
		return this.buildVo(cronJob);
	}

	@Transactional
	@Override
	public void cancelCronJob(Integer id){
		TbCronJob cronJob = this.tbCronJobDao.getCronJobById(id) ;
		if (CommonEnum.CommonStatusEnum.DEL.getCode().equals(cronJob.getStatus())){
			throw new BadRequestException("已是注销状态") ;
		}
		cronJob.setStatus(CommonEnum.CommonStatusEnum.DEL.getCode());
		cronJob.setEnable(CommonEnum.FlagEnum.FALSE_FLAG.getCode());
		this.tbCronJobDao.save(cronJob);
	}


	@Transactional
	@Override
	public void disableJob(List<Integer> jobIdList) {
		jobIdList.forEach((jobId)->{
			TbCronJob cronJob = this.tbCronJobDao.getCronJobById(jobId) ;
			cronJob.setEnable(CommonEnum.FlagEnum.FALSE_FLAG.getCode());
			this.tbCronJobDao.save(cronJob);
		});
	}

	@Transactional
	@Override
	public List<CronJobVo> enableJob(List<Integer> jobIdList) {
		List<CronJobVo> cronJobVoList = new ArrayList<>();
		jobIdList.forEach((jobId)->{
			TbCronJob cronJob = this.tbCronJobDao.getCronJobById(jobId) ;
			cronJob.setEnable(CommonEnum.FlagEnum.TRUE_FLAG.getCode());
			this.tbCronJobDao.save(cronJob);
			cronJobVoList.add(this.buildVo(cronJob));
		});
		return cronJobVoList;
	}

	@Override
	public List<CronJobVo> getAllEnableJob() {
		List<CronJobVo> cronJobVoList = new ArrayList<>();
		List<TbCronJob> cronJobList = this.tbCronJobDao.findAllEnableJob();
		if (CollectionUtil.isNotEmpty(cronJobList)){
			cronJobList.forEach(item->cronJobVoList.add(this.buildVo(item)));
		}
		return cronJobVoList;
	}

}
